package com.cloudkinto.service.orderrepair.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cloudkinto.common.DicBusinessConstant;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.common.DateUtils;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.MathUtils;
import com.cloudkinto.common.utils.StringsUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.extentity.ProductStockDetailDto;
import com.cloudkinto.extentity.orderrepair.OrderRepairComponentDto;
import com.cloudkinto.extentity.orderrepair.OrderRepairPageDto;
import com.cloudkinto.extentity.orderrepair.OrderRepairSkuDto;
import com.cloudkinto.extentity.stock.PickupStockRackDto;
import com.cloudkinto.extentity.stock.ProductStockDto;
import com.cloudkinto.extentity.stock.ProductStockTotalDto;
import com.cloudkinto.service.company.CompanyService;
import com.cloudkinto.service.dic.DicBusinessItemNewService;
import com.cloudkinto.service.dic.DicBusinessItemService;
import com.cloudkinto.service.dic.vo.LanguageValueEntity;
import com.cloudkinto.service.dic.vo.dicBusinessItem.DicBusinessNewEntity;
import com.cloudkinto.service.file.FileMoreService;
import com.cloudkinto.service.finance.CostRecordService;
import com.cloudkinto.service.finance.vo.RepairBillExportVo;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.orderrepair.OrderRepairLabelService;
import com.cloudkinto.service.orderrepair.OrderRepairService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;

import com.cloudkinto.service.orderrepair.vo.*;
import com.cloudkinto.service.product.ProductStockFlowingService;
import com.cloudkinto.service.product.ProductStockRackService;
import com.cloudkinto.service.shop.ShopService;
import com.cloudkinto.service.stock.StockLogService;
import com.cloudkinto.service.stock.StockRecordService;
import com.cloudkinto.service.storage.StorageService;
import com.cloudkinto.utils.BarCodePdfUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author hua
 * @since 2023-06-14
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class OrderRepairServiceImpl extends ServiceImpl<OrderRepairDao, OrderRepairDo> implements OrderRepairService {
    @Autowired
    private OrderRepairDao dao;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DicBusinessItemNewService dicBusinessItemNewService;
    @Autowired
    private DicBusinessItemService dicBusinessItemService;
    @Autowired
    private OrderRepairSkuDao orderRepairSkuDao;
    @Autowired
    private OrderRepairSnDao orderRepairSnDao;
    @Autowired
    private FileMoreService fileMoreService;
    @Autowired
    private OperateRecordService operateRecordService;
    @Autowired
    private StorageService storageService;
    @Autowired
    private StockRecordDao stockRecordDao;
    @Autowired
    private StockLogService stockLogService;
    @Autowired
    private ShopService shopService;
    @Autowired
    private ProductStockDao productStockDao;
    @Autowired
    private ProductStockRackDao productStockRackDao;
    @Autowired
    private ProductStockRackService productStockRackService;
    @Autowired
    private ProductStockFlowingService productStockFlowingService;
    @Autowired
    private OrderRepairLabelService orderRepairLabelService;
    @Autowired
    private OrderBackDao orderBackDao;
    @Autowired
    private StockRecordService stockRecordService;
    @Autowired
    private CostRecordService mCostService;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private ExchangeRateDao exchangeRateDao;
    @Autowired
    private OrderRepairRackDao orderRepairRackDao;
    @Autowired
    private StoragePositionDao storagePositionDao;
    @Autowired
    private StockLogService stockLogDao;

    @Override
    public SingleResult addInit() {
        Map<String, Object> result = new HashMap<>();
        List<LanguageValueEntity> idAndNameEntities = new ArrayList<>();
        idAndNameEntities.add(new LanguageValueEntity(DicBusinessItemConstant.CurrencyTypeRmb.intValue(), "人民币"));
        idAndNameEntities.add(new LanguageValueEntity(DicBusinessItemConstant.CurrencyTypeJpy.intValue(), "日币"));
        result.put("currencyType", idAndNameEntities);
        return SingleResult.success(result);
    }

    @Override
    public void add(OrderRepairAddReq req, Long userId) {
        if (req.getSkuList() == null || req.getSkuList().size() == 0) {
            throw new BizException(SysConstant.No_Data);
        }
        OrderBackDo backDo;
        if (req.getBackId() == null) {
            if (StringUtils.isBlank(req.getBackNo())) {
                backDo = null;
            } else {
                backDo = orderBackDao.selectOne(new LambdaQueryWrapper<OrderBackDo>()
                        .eq(OrderBackDo::getOrderOutNumber, req.getBackNo()).eq(OrderBackDo::getCompanyId, req.getCompanyId()).last(" order by id desc limit 1"));
            }
        } else {
            backDo = orderBackDao.selectOne(new LambdaQueryWrapper<OrderBackDo>()
                    .eq(OrderBackDo::getId, req.getBackId()).eq(OrderBackDo::getCompanyId, req.getCompanyId()));
        }
        OrderRepairDo entityDo = new OrderRepairDo();
        BeanUtils.copyProperties(req, entityDo);
        if (backDo != null) {
            entityDo.setBackId(backDo.getId());
        }
        entityDo.setStatus(StaticDict.Order_Repair_Status_Type.ToCheck.getValue());
        handlerAddBefore(entityDo, userId);
        dao.insert(entityDo);

        //插入操作记录
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_Create.getValue(), entityDo.getId(), userId, 9);
        //插入标签
        orderRepairLabelService.updateLabel(entityDo.getId(), req.getLabelIds(), userId);
        //插入skuList
        for (int i = 0; i < req.getSkuList().size(); i++) {
            if (i != 0) {
                break;
            }
            OrderRepairSkuAddReq skuReq = req.getSkuList().get(i);
            this.insertSku(entityDo.getId(), skuReq.getProductId(), skuReq.getQuantity(), userId);
        }
        //插入部件
        if (req.getComponentList() != null) {
            for (OrderRepairComponentAddReq componentReq : req.getComponentList()) {
                this.insertComponent(componentReq, entityDo.getId(), userId);
            }
        }

        //附件处理
        fileMoreService.dealFileList(req.getFileList(), entityDo.getId(), StaticDict.File_Type.RepairAttach.getValue(), userId);

        if (backDo != null) {
            backDo.setStatus(DicBusinessItemConstant.orderBackFinish);
            backDo.setUpdateBy(userId);
            backDo.setUpdateTime(new Date());
            orderBackDao.updateById(backDo);
            operateRecordService.operateAddRecord(SysConstant.OPERATE_DEAL_BACK, backDo.getId(), userId, 8);
        }

    }


    /**
     * 选择标签初始化
     *
     * @param companyId
     * @return
     */
    @Override
    public List<Map> repairCategoryInit(Long companyId) {
        return dicBusinessItemNewService.repairCategoryInit(companyId);
    }

    /**
     * 新增编辑标签
     *
     * @param idAndNameEntity
     * @return
     */
    @Override
    public void addOrUpdateCategory(DicBusinessNewEntity idAndNameEntity) {
        if (idAndNameEntity.getValue() == null || "".equals(idAndNameEntity.getValue())) {
            throw new BizException(SysConstant.OrderRepair_Input_LabelName);
        }

        DicBusinessItemNewDo dicBusinessItemDo = dicBusinessItemNewService.getOne(new LambdaQueryWrapper<DicBusinessItemNewDo>()
                .eq(DicBusinessItemNewDo::getDicItemValue, idAndNameEntity.getValue())
                .and(i -> i.eq(DicBusinessItemNewDo::getCompanyId, idAndNameEntity.getCompanyId()).or().isNull(DicBusinessItemNewDo::getCompanyId))
//                .eq(DicBusinessItemNewDo::getCompanyId, idAndNameEntity.getCompanyId())
                .and(i -> i.eq(DicBusinessItemNewDo::getDicBusinessId, DicBusinessConstant.repairLabelCanNotEdit).or().eq(DicBusinessItemNewDo::getDicBusinessId, DicBusinessConstant.repairLabelCanEdit))
                .last(" order by id desc limit 1"));
        if (dicBusinessItemDo != null) {
            throw new BizException(SysConstant.OrderRepair_LabelName_Repeat, idAndNameEntity.getValue());
        }
        dicBusinessItemDo = new DicBusinessItemNewDo();
        if (idAndNameEntity.getId() != 0) {
            dicBusinessItemDo.setId(Long.parseLong(idAndNameEntity.getId() + ""));
        }
        dicBusinessItemDo.setDicBusinessId(DicBusinessConstant.repairLabelCanNotEdit);
        dicBusinessItemDo.setDicItemValue(idAndNameEntity.getValue());
//        dicBusinessItemDo.setCompanyId(idAndNameEntity.getCompanyId());
        boolean flag = dicBusinessItemNewService.saveOrUpdate(dicBusinessItemDo);
        if (!flag) {
            throw new BizException(SysConstant.Operate_Failure);
        }
    }

    //新增校验
    private void addCheck(Object req) {

    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderRepairDo entityDo, Long userId) {
        entityDo.setCreateBy(userId);
        entityDo.setCreateTime(new Date());
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
        OrderRepairDo lastProductDo = dao.selectOne(new LambdaQueryWrapper<OrderRepairDo>()
                .last(String.format(" and DATE_FORMAT(create_time,'%1$s') = '%2$s' order by id desc limit 1", "%Y-%m-%d", DateUtils.dateFormatToString(new Date()))));
        StringBuilder buffer = new StringBuilder("OR");
        buffer.append(DateUtils.dateFormatToString(new Date(), "yyyyMMdd"));
        if (lastProductDo == null) {
            //说明今天是第一单
            buffer.append("0001");
        } else {
            int number = Integer.parseInt(lastProductDo.getRepairNo().substring(10)) + 1;
            buffer.append(number);
            while (buffer.length() < 14) {
                buffer.insert(10, 0);
            }
        }
        entityDo.setRepairNo(buffer.toString());
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(OrderRepairDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success(this.detail(id));
    }

    @Override
    public Object update(OrderRepairUpdateReq req, Long userId) {
        OrderRepairDo entityDo = dao.selectById(req.getId());
        if (entityDo == null) {
            throw new BizException(SysConstant.Error_Data_NotExist);
        }
        OrderBackDo backDo = null;
        if (entityDo.getBackId() == null && StringUtils.isNotBlank(req.getBackNo())) {
            backDo = orderBackDao.selectOne(new LambdaQueryWrapper<OrderBackDo>()
                    .eq(OrderBackDo::getOrderOutNumber, req.getBackNo()).eq(OrderBackDo::getCompanyId, entityDo.getCompanyId()));
            if (backDo != null) {
                entityDo.setBackId(backDo.getId());
            }
        }
        BeanUtils.copyProperties(req, entityDo);
        dao.updateById(entityDo);
        //插入操作记录
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_Update.getValue(), entityDo.getId(), userId, 9);
        //插入标签
        orderRepairLabelService.updateLabel(entityDo.getId(), req.getLabelIds(), userId);
        //只有待确认 才可以 插入skuList
        if ((StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(entityDo.getStatus()) || StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(entityDo.getStatus()))) {
            for (int i = 0; i < req.getSkuList().size(); i++) {
                if (i != 0) {
                    break;
                }
                OrderRepairSkuUpdateReq skuReq = req.getSkuList().get(i);
                if (skuReq.getId() != null) {
                    OrderRepairSkuDo sku = orderRepairSkuDao.selectById(skuReq.getId());
                    sku.setQuantity(skuReq.getQuantity());
                    orderRepairSkuDao.updateById(sku);
                } else {
                    this.insertSku(entityDo.getId(), skuReq.getProductId(), skuReq.getQuantity(), userId);
                }
            }
        }
        //维修完成之前才可以 修改插入部件
        if ((StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(entityDo.getStatus()) ||
                StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(entityDo.getStatus()) ||
                StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(entityDo.getStatus()))
                && req.getComponentList() != null) {
            for (OrderRepairComponentUpdateReq componentReq : req.getComponentList()) {
                if (componentReq.getId() != null) {
                    OrderRepairSkuDo component = orderRepairSkuDao.selectById(componentReq.getId());
                    if (component == null) {
                        throw new BizException(SysConstant.No_Data);
                    }
                    BeanUtils.copyProperties(componentReq, component);
                    orderRepairSkuDao.updateById(component);
                } else {
                    this.insertComponent(componentReq, entityDo.getId(), userId);
                }
            }
        }

        //附件处理
        fileMoreService.dealFileList(req.getFileList(), entityDo.getId(), StaticDict.File_Type.RepairAttach.getValue(), userId);
        //维修图片处理
        fileMoreService.dealFileList(req.getRepairFileList(), entityDo.getId(), StaticDict.File_Type.RepairPic.getValue(), userId);


        if (backDo != null) {
            backDo.setStatus(DicBusinessItemConstant.orderBackFinish);
            backDo.setUpdateBy(userId);
            backDo.setUpdateTime(new Date());
            orderBackDao.updateById(backDo);
            operateRecordService.operateAddRecord(SysConstant.OPERATE_DEAL_BACK, backDo.getId(), userId, 8);
        }
        return null;
    }


    /**
     * 删除sku
     */
    @Override
    public void deleteSku(DeleteSkuOrComponentReq req, Long userId) {
        OrderRepairDo entityDo = dao.selectById(req.getId());
        if (entityDo == null) {
            throw new BizException(SysConstant.Error_Data_NotExist);
        }
        if ("sku".equals(req.getType())) {
            //sku 完成指示之前可以删除 sku
            if (!(StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(entityDo.getStatus()) || StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(entityDo.getStatus()))) {
                throw new BizException(SysConstant.OrderRepair_Sku_Delete_ERROR);
            }
        } else if ("component".equals(req.getType())) {
            //部件   维修完成之前才可以 删除部件.因为维修完成就需要去 扣减库存
            if (!(StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(entityDo.getStatus()) ||
                    StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(entityDo.getStatus()) ||
                    StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(entityDo.getStatus()))) {
                throw new BizException(SysConstant.OrderRepair_Component_Delete_ERROR);
            }

        } else {
            throw new BizException(SysConstant.No_Data);
        }

        OrderRepairSkuDo et = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>()
                .eq(OrderRepairSkuDo::getRepairId, entityDo.getId()).eq(OrderRepairSkuDo::getId, req.getChildId())
                .eq(OrderRepairSkuDo::getType, req.getType()));
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        ProductInfoDo productInfoDo = productInfoDao.selectObject(et.getProductId());
        orderRepairSkuDao.deleteById(et.getId());

        //操作日志
        operateRecordService.operateAddRecordAndValue("sku".equals(req.getType()) ? StaticDict.Order_Repair_Operate_Type.OrderRepair_DeleteSku.getValue() : StaticDict.Order_Repair_Operate_Type.OrderRepair_DeleteComponent.getValue(),
                productInfoDo.getCommoditySku(), entityDo.getId(), userId, 9);
    }


    public void insertSku(Long id, Long productId, int quantity, Long userId) {
        if (quantity <= 0) {
            throw new BizException(SysConstant.OrderRepair_Add_Sku);
        }
        OrderRepairSkuDo skuDo = new OrderRepairSkuDo();
        skuDo.setRepairId(id);
        skuDo.setType("sku");
        skuDo.setProductId(productId);
        skuDo.setQuantity(quantity);
        skuDo.setCreateBy(userId);
        skuDo.setCreateTime(new Date());
        orderRepairSkuDao.insert(skuDo);
    }

    public OrderRepairSkuDo insertComponent(OrderRepairComponentAddReq componentReq, Long id, Long userId) {
        OrderRepairSkuDo componentDo = new OrderRepairSkuDo();
        if (componentReq.getShopId() == null) {
            throw new BizException(SysConstant.No_Data);
        }
        BeanUtils.copyProperties(componentReq, componentDo);
        componentDo.setType("component");
        componentDo.setRepairId(id);
        componentDo.setCreateTime(new Date());
        componentDo.setCreateBy(userId);
        orderRepairSkuDao.insert(componentDo);
        return componentDo;
    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderRepairDo entityDo, Long userId) {
        entityDo.setUpdateBy(userId);
        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private Object handlerUpdateAfter(OrderRepairDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public int delete(Long id, Long userId) {
        OrderRepairDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderRepairDo entityDo, Long userId) {
    }

    @Override
    public OrderRepairDetailRes detail(Long id) {
        OrderRepairDetailRes res = new OrderRepairDetailRes();
        OrderRepairDo entityDo = dao.selectById(id);
        if (entityDo == null) {
            throw new BizException(SysConstant.Error_Data_NotExist);
        }
        BeanUtils.copyProperties(entityDo, res);


        //故障标签id
        List<DicBusinessItemNewDo> itemNewDoList = dao.getLabelItemList(id);
        List<Long> labelIds = itemNewDoList.stream().map(DicBusinessItemNewDo::getId).collect(Collectors.toList());
        res.setLabelIds(labelIds);

        //Sku信息
        res.setSkuList(this.getSkuList(id, entityDo.getCompanyId(), entityDo.getStorageId()));
        //部件信息
        res.setComponentList(this.getComponent(entityDo));

        //附件
        res.setFileList(fileMoreService.getFileList(id, StaticDict.File_Type.RepairAttach.getValue()));
        //维修图片
        res.setRepairFileList(fileMoreService.getFileList(id, StaticDict.File_Type.RepairPic.getValue()));
        //操作日志
        List<OperateRes> operateResList = operateRecordService.getOperateList(entityDo.getId(), 9);
        res.setRecordList(operateResList);
        return res;
    }

    /**
     * 获取部件信息
     *
     * @return
     */
    public List<OrderRepairComponentRes> getComponent(OrderRepairDo et) {
        List<OrderRepairComponentRes> componentList = new ArrayList<>();
        List<OrderRepairComponentDto> componentDtoList = orderRepairSkuDao.getComponentDtoList(et.getId());
        for (OrderRepairComponentDto componentDto : componentDtoList) {
            OrderRepairComponentRes componentRes = new OrderRepairComponentRes();
            BeanUtils.copyProperties(componentDto, componentRes);
            //获取库存信息
            Map<String, String> map = new HashMap<>();
            map.put("productId", componentDto.getProductId() + "");
            map.put("storageId", et.getStorageId() + "");
            map.put("companyId", et.getCompanyId() + "");
            List<PickupStockRackDto> stockRackList;
            //倒序获取库位货存 可做到先进先出
            synchronized (this) {
                stockRackList = productStockRackDao.getStockRackBySort(map);
            }
            Map<Long, Integer> stockMap = new HashMap<>();
            for (PickupStockRackDto stockRackDo : stockRackList) {
                stockMap.merge(stockRackDo.getRackId(), stockRackDo.getGoodQuantity(), Integer::sum);
            }
            //库位信息
            List<RackMsgRes> rackList = new ArrayList<>();
            List<OrderRepairRackDo> list = orderRepairRackDao.selectList(new LambdaQueryWrapper<OrderRepairRackDo>().eq(OrderRepairRackDo::getComponentId, componentDto.getId()));
            if (list.size() != 0) {
                for (OrderRepairRackDo ra : list) {
                    RackMsgRes rackMsg = new RackMsgRes();
                    BeanUtils.copyProperties(ra, rackMsg);
                    if (rackMsg.getRackId() == null) {
                        rackMsg.setPositionName("默认库位");
                    } else {
                        StoragePositionDo positionDo = storagePositionDao.selectById(rackMsg.getRackId());
                        rackMsg.setPositionName(positionDo.getPositionName());
                    }
                    rackMsg.setGoodQuantity(stockMap.get(ra.getRackId()));
                    rackList.add(rackMsg);
                }
            } else {
                //去获取推荐库位
                int goodQuantity = componentDto.getQuantity();
                for (PickupStockRackDto st : stockRackList) {
                    if (st.getGoodQuantity() <= 0) {
                        continue;
                    }
                    RackMsgRes rackMsg = new RackMsgRes();
                    rackMsg.setRackId(st.getRackId());
                    rackMsg.setGoodQuantity(stockMap.get(st.getRackId()));
                    if (st.getRackId() == null) {
                        rackMsg.setPositionName("默认库位");
                    } else {
                        rackMsg.setPositionName(st.getPositionName());
                    }
                    if (st.getGoodQuantity() > goodQuantity) {
                        rackMsg.setQuantity(goodQuantity);
                        st.setGoodQuantity(st.getGoodQuantity() - goodQuantity);
                        goodQuantity = 0;
                    } else {
                        rackMsg.setQuantity(st.getGoodQuantity());
                        goodQuantity -= st.getGoodQuantity();
                        st.setGoodQuantity(0);
                    }
                    rackList.add(rackMsg);
                    if (goodQuantity <= 0) {
                        break;
                    }
                }

            }
            componentRes.setRackList(rackList);
            componentList.add(componentRes);
        }
        return componentList;
    }

    /**
     * 获取sku信息
     *
     * @param id
     * @return
     */
    public List<OrderRepairSkuRes> getSkuList(Long id, Long companyId, Long storageId) {
        List<OrderRepairSkuRes> skuList = new ArrayList<>();
        List<OrderRepairSkuDto> skuDoList = orderRepairSkuDao.getSkuDtoList(id);
        for (OrderRepairSkuDto skuDto : skuDoList) {
            OrderRepairSkuRes skuRes = new OrderRepairSkuRes();
            BeanUtils.copyProperties(skuDto, skuRes);
            if (StringUtils.isNotBlank(skuDto.getSnNo()) && skuDto.getSnNo().length() >= 13) {
                skuRes.setSnNo(skuDto.getSnNo().substring(0, 13));
            }
            List<ProductStockDto> productList = productStockRackService.getProductList("", 0L, storageId, skuDto.getProductId(), companyId, 1);
            skuRes.setGoodQuantity(productList.size() > 0 ? productList.stream().mapToInt(ProductStockDto::getBadQuantity).sum() : 0);
            skuRes.setBadQuantity(skuRes.getGoodQuantity());
            skuList.add(skuRes);
        }
        return skuList;
    }

    //查询明细之后要执行的业务定制处理
    private Object handlerDetailAfter(Object res) {
        return res;
    }

    @Override
    public SingleResult pageInit() {
        Map<String, Object> result = new HashMap<>();
        result.put("statusTypeList", this.getStatusTypeList());
        //产品分类
        result.put("productTypeList", dicBusinessItemService.getDicItemList(DicBusinessConstant.productType));
        result.put("companyList", companyService.getList().getData());
        result.put("storageList", storageService.getStorageList());
        return SingleResult.success(result);
    }

    public List<Map<String, String>> getStatusTypeList() {
        List<Map<String, String>> list = new ArrayList<>();
        for (StaticDict.Order_Repair_Status_Type value : StaticDict.Order_Repair_Status_Type.values()) {
            Map<String, String> map = new HashMap<>();
            map.put("id", value.getValue());
            map.put("value", StringsUtil.createI18Message(value.getText()));
            list.add(map);
        }
        return list;
    }

    @Override
    public List<OrderRepairPageRes> getList(Map<String, String> map) {
        List<OrderRepairPageDto> list = dao.listPage(map);
        List<OrderRepairPageRes> resList = handlerListAfter(list);
        return resList;
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        IPage<OrderRepairPageDto> page = pageInitDto(map);
        page = dao.listPage(page, map);
        List<OrderRepairPageRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }

    @Override
    public List<RepairBillExportVo> handlerBillListAfter(List<String> ids) {
        List<RepairBillExportVo> result = new ArrayList<>();
        List<OrderRepairPageDto> orderRepairPageDtos = dao.listPageByIds(ids);
        for (OrderRepairPageDto et : orderRepairPageDtos) {
            RepairBillExportVo res = new RepairBillExportVo();
            BeanUtils.copyProperties(et, res);
            //故障标签
            List<DicBusinessItemNewDo> itemList = dao.getLabelItemList(et.getId());
            StringBuilder labelName = new StringBuilder();
            for (DicBusinessItemNewDo dicBusinessItemNewDo : itemList) {
                if (labelName.length() > 0) {
                    labelName.append(",");
                }
                labelName.append(StringsUtil.createI18Message(dicBusinessItemNewDo.getDicItemValue()));
            }
            res.setLabelName(labelName.toString());

            //sn码处理一下，只显示第一个
            if (StringUtils.isNotBlank(res.getSnNo()) && res.getSnNo().length() >= 13) {
                res.setSnNo(res.getSnNo().substring(0, 13));
            }
            result.add(res);
        }
        return result;
    }

    //查询分页列表之后对列表数据的处理
    private List<OrderRepairPageRes> handlerListAfter(List<OrderRepairPageDto> list) {
        List<OrderRepairPageRes> result = new ArrayList<>();
        for (OrderRepairPageDto et : list) {
            OrderRepairPageRes res = new OrderRepairPageRes();
            BeanUtils.copyProperties(et, res);
            //故障标签
            List<DicBusinessItemNewDo> itemList = dao.getLabelItemList(et.getId());
            StringBuilder labelName = new StringBuilder();
            for (DicBusinessItemNewDo dicBusinessItemNewDo : itemList) {
                if (labelName.length() > 0) {
                    labelName.append(",");
                }
                labelName.append(StringsUtil.createI18Message(dicBusinessItemNewDo.getDicItemValue()));
            }
            res.setLabelName(labelName.toString());

            //sn码处理一下，只显示第一个
            if (StringUtils.isNotBlank(res.getSnNo()) && res.getSnNo().length() >= 13) {
                res.setSnNo(res.getSnNo().substring(0, 13));
            }
            result.add(res);
        }
        return result;
    }

    private IPage<OrderRepairDo> pageInit(Map<String, String> map) {
        IPage<OrderRepairDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private IPage<OrderRepairPageDto> pageInitDto(Map<String, String> map) {
        IPage<OrderRepairPageDto> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<OrderRepairDo> queryBuild(Map<String, String> map) {
        QueryWrapper<OrderRepairDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.like("keyword", map.get("keyword"));
        }
        return wrapper;
    }


    /**
     * 仓库才能标记确认
     */
    @Override
    public void markConfirm(Long id, Long userId) {
        OrderRepairDo et = dao.selectById(id);
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(et.getStatus())) {
            throw new BizException(SysConstant.OrderRepair_Check_Error);
        }
        et.setStatus(StaticDict.Order_Repair_Status_Type.Checked.getValue());
        et.setUpdateBy(userId);
        et.setUpdateTime(new Date());
        dao.updateById(et);

        //操作日志
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_MarkConfirm.getValue(), id, userId, 9);
    }


    @Override
    public void discard(Long id, Long userId) {
        OrderRepairDo et = dao.selectById(id);
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!(StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(et.getStatus()) || StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(et.getStatus()))) {
            throw new BizException(SysConstant.OrderRepair_Repair_Error);
        }
        et.setStatus(StaticDict.Order_Repair_Status_Type.Discard.getValue());
        et.setUpdateBy(userId);
        et.setUpdateTime(new Date());
        dao.updateById(et);
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_Discard.getValue(), id, userId, 9);
    }

    /**
     * 开始维修
     */
    @Override
    public void beginRepair(BeginRepairReq req, Long userId) {
        OrderRepairDo et = dao.selectById(req.getId());
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(et.getStatus())) {
            throw new BizException(SysConstant.OrderRepair_Repair_Error);
        }
        if (req.getSkuList() == null || req.getSkuList().size() == 0) {
            throw new BizException(SysConstant.No_Data);
        }
        BeginRepairSkuReq skuReq = req.getSkuList().get(0);
        OrderRepairSkuDo skuDo = orderRepairSkuDao.selectById(skuReq.getId());
        if (skuDo == null) {
            throw new BizException(SysConstant.No_Data);
        }

        if (et.getType() == 1) {
            //库内维修
            if (req.getSkuList().get(0).getRackList() == null) {
                throw new BizException(SysConstant.No_Data);
            }
            if (skuReq.getRackList().stream().mapToInt(RackMsg::getQuantity).sum() != skuDo.getQuantity()) {
                throw new BizException(SysConstant.No_Data);
            }
            Map<Long, Integer> shopCount = new HashMap<>();
            //去冻结旧表库存 随机冻结 店铺库存
            List<StockRecordDo> recordDoList = stockRecordDao.selectList(new LambdaQueryWrapper<StockRecordDo>()
                    .eq(StockRecordDo::getProductInfoId, skuDo.getProductId())
                    .eq(StockRecordDo::getStorageId, et.getStorageId())
                    .gt(StockRecordDo::getCanotSellCount, 0));
            int quantity = skuDo.getQuantity();
            for (StockRecordDo stockRecordDo : recordDoList) {
                int repairingCount = 0;
                if (stockRecordDo.getCanotSellCount() > quantity) {
                    repairingCount = quantity;
                    quantity = 0;
                } else {
                    repairingCount = stockRecordDo.getCanotSellCount();
                    quantity -= stockRecordDo.getCanotSellCount();
                }
                //冻结
                stockRecordDo.setCanotSellCount(stockRecordDo.getCanotSellCount() - repairingCount);
                stockRecordDo.setRepairingCount(stockRecordDo.getRepairingCount() + repairingCount);
                stockRecordDao.updateById(stockRecordDo);
//                stockLogDao.saveAutoSendOutLog(skuDo.getProductId(), stockRecordDo.getShopId(), stockRecordDo.getStorageId(),
//                        -repairingCount, stockRecordDo.getCanSellCount(), stockRecordDo.getCompanyId(), userId, et.getRepairNo());
                stockLogService.saveAutoSendOutLog(1, skuDo.getProductId(), stockRecordDo.getShopId(), stockRecordDo.getStorageId(),
                        -repairingCount, stockRecordDo.getCanotSellCount(), stockRecordDo.getCompanyId(), userId, et.getRepairNo());
                if (repairingCount > 0) {
                    shopCount.put(stockRecordDo.getShopId(), repairingCount);
                }
                if (quantity <= 0) {
                    break;
                }
            }
            if (quantity > 0) {
                throw new BizException(SysConstant.Product_Stock_NotEnough);
            }
            //再去操作新表库存，将新表库存移入默认库位维修区
            for (RackMsg rackMsg : skuReq.getRackList()) {
                Map<String, String> map = new HashMap<>();
                map.put("productId", skuDo.getProductId() + "");
                if (rackMsg.getRackId() != null) {
                    map.put("rackId", rackMsg.getRackId() + "");
                }
                map.put("storageId", et.getStorageId() + "");
                map.put("companyId", et.getCompanyId() + "");
                map.put("store", "0");
                List<ProductStockRackDo> rackDoList = productStockRackDao.getStockRackList(map);
                for (ProductStockRackDo rackDo : rackDoList) {
                    ProductStockDo stockDo = productStockDao.selectById(rackDo.getStockId());
                    if (stockDo == null) {
                        throw new BizException(SysConstant.No_Data);
                    }
                }
                int goodQuantity = rackMsg.getQuantity();

                String fromRackName = "默认库位";
                if (rackMsg.getRackId() != null) {
                    StoragePositionDo from = storagePositionDao.selectById(rackMsg.getRackId());
                    fromRackName = from.getPositionName();
                }
                for (ProductStockRackDo rackDo : rackDoList) {
                    //减库存
                    Map<String, Integer> resultMap = productStockRackService.dealWithOneRackStock(0, goodQuantity, rackDo, StaticDict.Product_Flowing_Type.OrderRepair.getValue(), null, fromRackName + " 库内维修调出至维修区", userId);
                    int dGood = resultMap.get("dGood");
                    int dBad = resultMap.get("dBad");
                    goodQuantity = resultMap.get("badQuantity");

                    //减完库存再去新增 到维修区
                    ProductStockRackDo newRackDo = new ProductStockRackDo();
                    newRackDo.setStockId(rackDo.getStockId());
                    newRackDo.setRackId(null);//默认都到默认库位 维修区
                    newRackDo.setGoodQuantity(dGood);
                    newRackDo.setBadQuantity(dBad);
                    newRackDo.setCreateTime(new Date());
                    newRackDo.setStore(2);//维修区
                    if (newRackDo.getGoodQuantity() != 0 || newRackDo.getBadQuantity() != 0) {
                        productStockRackDao.insert(newRackDo);
                    }
                    ProductStockDo stockDo = productStockDao.selectById(rackDo.getStockId());

                    if (dGood != 0 || dBad != 0) {
                        //库存流水新
                        productStockFlowingService.insertFlowing(StaticDict.Product_Flowing_Type.OrderRepair.getValue(), stockDo.getProductId(), et.getStorageId(), dGood, dBad, null, stockDo.getCompanyId(), userId, fromRackName + " 库内维修调入至维修区");
                    }
                    if (goodQuantity <= 0) {
                        break;
                    }
                }
                if (goodQuantity > 0) {
                    ProductInfoDo productInfoDo = productInfoDao.selectObject(skuDo.getProductId());
                    throw new BizException(SysConstant.Product_Stock_NotEnough_Sku, productInfoDo.getCommoditySku());
                }
            }
        } else {
            //退货维修 直接增加 维修中库存，
            ShopDo shopDo = shopService.getOne(new LambdaQueryWrapper<ShopDo>().eq(ShopDo::getCompanyId, et.getCompanyId()).last(" order by id desc limit 1"));
            if (shopDo == null) {
                throw new BizException(SysConstant.No_Data);
            }
            StockRecordDo stockRecordDo = stockRecordDao.selectOne(new LambdaQueryWrapper<StockRecordDo>()
                    .eq(StockRecordDo::getProductInfoId, skuDo.getProductId())
                    .eq(StockRecordDo::getStorageId, et.getStorageId())
                    .eq(StockRecordDo::getShopId, shopDo.getId()));
            if (stockRecordDo != null) {
                stockRecordDo.setRepairingCount(stockRecordDo.getRepairingCount() + skuDo.getQuantity());
                stockRecordDo.setUpdateBy(userId);
                stockRecordDo.setUpdateTime(new Date());
                stockRecordDao.updateById(stockRecordDo);
            } else {
                stockRecordDo = new StockRecordDo();
                stockRecordDo.setStorageId(et.getStorageId());
                stockRecordDo.setRepairingCount(skuDo.getQuantity());
                stockRecordDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                stockRecordDo.setCompanyId(et.getCompanyId());
                stockRecordDo.setProductInfoId(skuDo.getProductId());
                stockRecordDo.setShopId(shopDo.getId());
                stockRecordDo.setUpdateBy(userId);
                stockRecordDo.setUpdateTime(new Date());
                stockRecordDao.insert(stockRecordDo);
            }

            //再去添加 新表库存

            ProductStockDo stockDo = new ProductStockDo();
            stockDo.setCompanyId(et.getCompanyId());
            stockDo.setCreateBy(userId);
            stockDo.setCreateTime(new Date());
            stockDo.setProductId(skuDo.getProductId());
            stockDo.setStorageId(et.getStorageId());
            stockDo.setReceiveGoodQuantity(0);
            stockDo.setBadQuantity(skuDo.getQuantity());
            stockDo.setGoodQuantity(0);
            stockDo.setReceiveQuantity(stockDo.getGoodQuantity() + stockDo.getBadQuantity());
            stockDo.setOrderId(et.getId());
            stockDo.setOrderType("OR");//入库单

            productStockDao.insert(stockDo);
            //插入子表
            ProductStockRackDo rackDo = new ProductStockRackDo();
            rackDo.setGoodQuantity(stockDo.getGoodQuantity());
            rackDo.setBadQuantity(stockDo.getBadQuantity());
            rackDo.setStockId(stockDo.getId());
            rackDo.setStore(2);//维修中
            rackDo.setCreateTime(new Date());
            productStockRackDao.insert(rackDo);

            productStockFlowingService.insertFlowing(StaticDict.Product_Flowing_Type.OrderRepair.getValue(), et.getRepairNo(), null, skuDo.getProductId(), et.getStorageId(), rackDo.getGoodQuantity(),
                    rackDo.getBadQuantity(), 0, null, null, et.getCompanyId(), userId, "维修单:" + et.getRepairNo() + "入维修区");

        }

        et.setStatus(StaticDict.Order_Repair_Status_Type.Repairing.getValue());
        et.setBeginRepairTime(new Date());
        et.setUpdateBy(userId);
        et.setUpdateTime(new Date());
        dao.updateById(et);

        //操作日志
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_BeginRepair.getValue(), req.getId(), userId, 9);
    }


    @Override
    public FinishRepairInitRes beginRepairInit(Long id) {
        OrderRepairDo et = dao.selectById(id);
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(et.getStatus())) {
            throw new BizException(SysConstant.OrderRepair_Repair_Error);
        }
        FinishRepairInitRes initRes = new FinishRepairInitRes();
        initRes.setId(et.getId());
        initRes.setType(et.getType());
        initRes.setStorageId(et.getStorageId());
        //故障标签
        List<DicBusinessItemNewDo> itemNewDoList = dao.getLabelItemList(id);
        List<Long> labelIds = itemNewDoList.stream().map(DicBusinessItemNewDo::getId).collect(Collectors.toList());
        initRes.setLabelIds(labelIds);

        //Sku信息
        List<OrderRepairSkuRes> skuList = this.getSkuList(id, et.getCompanyId(), et.getStorageId());

        if (et.getType() == 1) {
            for (OrderRepairSkuRes skuRes : skuList) {
                //获取库存信息
                Map<String, String> map = new HashMap<>();
                map.put("productId", skuRes.getProductId() + "");
                map.put("storageId", et.getStorageId() + "");
                map.put("companyId", et.getCompanyId() + "");
//                map.put("store", "2");
                map.put("containBad", "1");
                List<ProductStockTotalDto> stockRackList;
                //倒序获取库位货存 可做到先进先出
                synchronized (this) {
                    stockRackList = productStockRackDao.getStockRackTotalBySort(map);
                }
//                Map<Long, Integer> stockMap = new HashMap<>();
//                for (PickupStockRackDto stockRackDo : stockRackList) {
//                    stockMap.merge(stockRackDo.getRackId(), stockRackDo.getGoodQuantity(), Integer::sum);
//                }
                //库位信息
                List<RackMsgRes> rackList = new ArrayList<>();
                //去获取推荐库位
                int goodQuantity = skuRes.getQuantity();
                for (ProductStockTotalDto st : stockRackList) {
                    RackMsgRes rackMsg = new RackMsgRes();
                    rackMsg.setRackId(st.getRackId());
                    rackMsg.setGoodQuantity(st.getBadQuantity());
                    if (st.getRackId() == null) {
                        rackMsg.setPositionName("默认库位");
                    } else {
                        rackMsg.setPositionName(st.getPositionName());
                    }

                    if (st.getBadQuantity() > goodQuantity) {
                        rackMsg.setQuantity(goodQuantity);
                        st.setBadQuantity(st.getBadQuantity() - goodQuantity);
                        goodQuantity = 0;
                    } else {
                        rackMsg.setQuantity(st.getBadQuantity());
                        goodQuantity -= st.getBadQuantity();
                        st.setBadQuantity(0);
                    }
                    rackList.add(rackMsg);
                    if (goodQuantity <= 0) {
                        break;
                    }
                }
                skuRes.setRackList(rackList);
            }
        }
        initRes.setSkuList(skuList);

        initRes.setComponentList(this.getComponent(et));
        //维修图片信息
        initRes.setRepairFileList(fileMoreService.getFileList(id, StaticDict.File_Type.RepairPic.getValue()));
        return initRes;
    }


    @Override
    public FinishRepairInitRes finishRepairInit(Long id, Integer type) {
        if (type == null) {
            type = 0;
        }
        OrderRepairDo et = dao.selectById(id);
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (type == 0 && !StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(et.getStatus())) {
            throw new BizException(SysConstant.OrderRepair_FinishRepair_Error);
        }
        FinishRepairInitRes initRes = new FinishRepairInitRes();
        initRes.setId(et.getId());
        initRes.setStorageId(et.getStorageId());
        initRes.setType(et.getType());
        //故障标签
        List<DicBusinessItemNewDo> itemNewDoList = dao.getLabelItemList(id);
        List<Long> labelIds = itemNewDoList.stream().map(DicBusinessItemNewDo::getId).collect(Collectors.toList());
        initRes.setLabelIds(labelIds);
        //sn码
//        List<OrderRepairSnDo> snList = dao.getRepairSnList(id);
//        initRes.setSnNoList(snList.stream().map(OrderRepairSnDo::getSnNo).collect(Collectors.toList()));
        //Sku信息
        initRes.setSkuList(this.getSkuList(id, et.getCompanyId(), et.getStorageId()));
        //部件
        initRes.setComponentList(this.getComponent(et));
        //维修图片信息
        initRes.setRepairFileList(fileMoreService.getFileList(id, StaticDict.File_Type.RepairPic.getValue()));
        return initRes;
    }

    /**
     * 维修完成
     */
    @Override
    public void finishRepair(FinishRepairReq req, Long userId) {
        OrderRepairDo et = dao.selectById(req.getId());
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(et.getStatus())) {
            throw new BizException(SysConstant.OrderRepair_FinishRepair_Error);
        }
        if (req.getType() == 1) {
            et.setStatus(StaticDict.Order_Repair_Status_Type.Repaired.getValue());
            et.setRepairResult(0);//维修成功
            et.setCusIndicate(0);
        }
        et.setUpdateBy(userId);
        et.setUpdateTime(new Date());
        et.setFinishRepairTime(new Date());
        dao.updateById(et);

        this.updateComponent(et, req.getComponentList(), req.getType(), userId);

        OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>()
                .eq(OrderRepairSkuDo::getRepairId, et.getId()).eq(OrderRepairSkuDo::getType, "sku"));
        if (req.getType() == 1 || req.getType() == 2) {//维修完成 或部分维修完成
            //操作sku信息
            int partCount = req.getSkuList().get(0).getPartCount();

            //维修完成 直接上架
            List<StockRecordDo> list = stockRecordDao.selectList(new LambdaQueryWrapper<StockRecordDo>()
                    .eq(StockRecordDo::getStorageId, et.getStorageId())
                    .eq(StockRecordDo::getProductInfoId, skuDo.getProductId()).gt(StockRecordDo::getRepairingCount, 0));
            //维修完成 上架库存
            this.dealRepairingCount(list, et.getRepairNo(), partCount, skuDo.getProductId(), 1, userId);
            if (req.getType() == 1) {
                //维修完成 未维修数量删除
                this.dealRepairingCount(list, et.getRepairNo(), skuDo.getQuantity() - skuDo.getCount() - partCount, skuDo.getProductId(), 0, userId);

            }
            //保存到新表 新表解冻库存
            List<ProductStockRackDo> rackDoList = this.getRackList(skuDo.getProductId(), et.getStorageId(), et.getCompanyId(), "2");//维修区

            int quantity = req.getType() == 1 ? skuDo.getQuantity() - skuDo.getCount() : partCount;////上架 无论有没有全部维修完成 先全部移除解冻库存，再去添加已维修好的库存
            if (quantity != 0) {
                this.reduceBadQuantity(rackDoList, quantity, "维修完成解冻库存", userId);
                if (partCount != 0) {
                    //再去添加库存
                    ProductStockDo stockDo = new ProductStockDo();
                    stockDo.setCompanyId(et.getCompanyId());
                    stockDo.setCreateBy(userId);
                    stockDo.setCreateTime(new Date());
                    stockDo.setProductId(skuDo.getProductId());
                    stockDo.setStorageId(et.getStorageId());
                    stockDo.setGoodQuantity(partCount);
                    stockDo.setReceiveGoodQuantity(stockDo.getGoodQuantity());
                    stockDo.setBadQuantity(0);
                    stockDo.setReceiveQuantity(stockDo.getGoodQuantity() + stockDo.getBadQuantity());
                    stockDo.setOrderId(et.getId());
                    stockDo.setOrderType("OR");//入库单
//            stockDo.setShopId(orderInputDo.getShopId());
                    //单位成本 * 单位体积
                    productStockDao.insert(stockDo);

                    ProductStockRackDo rackDo = new ProductStockRackDo();
                    rackDo.setGoodQuantity(stockDo.getGoodQuantity());
                    rackDo.setBadQuantity(stockDo.getBadQuantity());
                    rackDo.setStockId(stockDo.getId());
                    rackDo.setRackId(req.getSkuList().get(0).getRackId());
                    rackDo.setCreateTime(new Date());
                    //是否存入备货区
                    rackDo.setStore(0);
                    productStockRackDao.insert(rackDo);

                    productStockFlowingService.insertFlowing(StaticDict.Product_Flowing_Type.OrderRepair.getValue(), et.getRepairNo(), null, skuDo.getProductId(), et.getStorageId(), rackDo.getGoodQuantity(),
                            rackDo.getBadQuantity(), 0, null, null, et.getCompanyId(), userId, "维修单:" + et.getRepairNo() + "入维修区");

                    skuDo.setCount(skuDo.getCount() + partCount);
                    if (skuDo.getCount() > skuDo.getQuantity()) {
                        throw new BizException(SysConstant.No_Data);
                    }
                    skuDo.setRackId(req.getSkuList().get(0).getRackId());
                    orderRepairSkuDao.updateById(skuDo);
                }
            }
        }

        //故障类型
        orderRepairLabelService.updateLabel(et.getId(), req.getLabelIds(), userId);
        //图片和视频
        fileMoreService.dealFileList(req.getRepairFileList(), et.getId(), StaticDict.File_Type.RepairPic.getValue(), userId);

        if (req.getType() == 1) {
            //操作日志
            operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_FinishRepair.getValue(), et.getId(), userId, 9);
        } else if (req.getType() == 2) {
            //部位维修完成
            operateRecordService.operateAddRecordAndValue(StaticDict.Order_Repair_Operate_Type.OrderRepair_PartRepair.getValue(), req.getSkuList().get(0).getPartCount() + "", et.getId(), userId, 9);
        } else {
            operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_Update.getValue(), et.getId(), userId, 9);
        }
    }


    public List<ProductStockRackDo> getRackList(Long productId, Long storageId, Long companyId, String store) {
        Map<String, String> map = new HashMap<>();
        map.put("productId", productId + "");
        map.put("storageId", storageId + "");
        map.put("companyId", companyId + "");
        map.put("store", store);//维修区
        return productStockRackDao.getStockRackList(map);
    }

    public void reduceBadQuantity(List<ProductStockRackDo> rackDoList, int quantity, String tips, Long userId) {
        for (ProductStockRackDo rackDo : rackDoList) {
            //单纯减库存，也要更新旧表库存
            Map<String, Integer> resultMap = productStockRackService.dealWithOneRackStock(0, quantity, rackDo, StaticDict.Product_Flowing_Type.OrderRepair.getValue(), null, tips, userId);
            int dGood = resultMap.get("dGood");
            int dBad = resultMap.get("dBad");
            if (dGood == 0 && dBad == 0) {
                continue;
            }
            quantity = resultMap.get("badQuantity");
            productStockDao.updateStockById2(rackDo.getStockId(), dGood, dBad);
            if (quantity <= 0) {
                break;
            }
        }
        if (quantity > 0) {
            throw new BizException(SysConstant.StockRack_Bad_NotEnough_New);
        }
    }


    public void updateComponent(OrderRepairDo et, List<OrderRepairComponentFinishReq> componentList, int type, Long userId) {
        if (type == 1) {
            for (OrderRepairComponentFinishReq componentReq : componentList) {
                Map<String, String> map = new HashMap<>();
                map.put("productId", componentReq.getProductId() + "");
                map.put("storageId", et.getStorageId() + "");
                map.put("companyId", et.getCompanyId() + "");
                if (componentReq.getQuantity() != 0 && (componentReq.getRackList() == null || componentReq.getRackList().size() == 0)) {
                    throw new BizException(SysConstant.No_Data);
                }
                for (RackMsg rackMsg : componentReq.getRackList()) {
                    if (rackMsg.getRackId() != null) {
                        map.put("rackId", rackMsg.getRackId() + "");
                    }
                    map.put("notStore", "1");
                    ProductStockDetailDto detailDto = productStockRackDao.getStockByRackId(map);
                    if (detailDto == null) {
                        throw new BizException(SysConstant.StockRack_Good_NotEnough);
                    }
                    if ((detailDto.getGoodQuantity() - rackMsg.getQuantity()) < 0) {
                        throw new BizException(SysConstant.StockRack_Good_NotEnough);
                    }
                }
            }
        }

        //更新部件 完成维修需要扣减 部件库存
        for (OrderRepairComponentFinishReq componentReq : componentList) {
            if (type == 1 && componentReq.getQuantity() != 0 && (componentReq.getRackList() == null || componentReq.getRackList().size() == 0)) {
                throw new BizException(SysConstant.No_Data);
            }
            //操作库存
            OrderRepairSkuDo component;
            if (componentReq.getId() != null) {
                component = orderRepairSkuDao.selectById(componentReq.getId());
                if (component == null) {
                    throw new BizException(SysConstant.No_Data);
                }
                //更新部件信息
                BeanUtils.copyProperties(componentReq, component);
                orderRepairSkuDao.updateById(component);
                //保存 库存信息
            } else {
                component = this.insertComponent(componentReq, et.getId(), userId);
            }
            if (componentReq.getRackList() != null && componentReq.getRackList().size() != 0) {
                //有库位信息
                orderRepairRackDao.delete(new LambdaQueryWrapper<OrderRepairRackDo>().eq(OrderRepairRackDo::getComponentId, component.getId())
                        .eq(OrderRepairRackDo::getRepairId, et.getId()));
                for (RackMsg rackMsg : componentReq.getRackList()) {
                    OrderRepairRackDo comRackDo = new OrderRepairRackDo();
                    comRackDo.setRackId(rackMsg.getRackId());
                    comRackDo.setQuantity(rackMsg.getQuantity());
                    comRackDo.setRepairId(et.getId());
                    comRackDo.setComponentId(component.getId());
                    comRackDo.setCreateBy(userId);
                    comRackDo.setCreateTime(new Date());
                    orderRepairRackDao.insert(comRackDo);
                }
            }

            if (type == 0 || type == 2 || componentReq.getQuantity() == 0) {
                //仅保存 不操作库存
                continue;
            }
            //先扣减旧表库存
            stockRecordService.deduceGoodStock(component.getProductId(), et.getStorageId(), component.getShopId(), component.getQuantity(), et.getRepairNo(), userId);

            for (RackMsg rackMsg : componentReq.getRackList()) {
                Map<String, String> map = new HashMap<>();
                map.put("productId", component.getProductId() + "");
                map.put("storageId", et.getStorageId() + "");
                map.put("companyId", et.getCompanyId() + "");
                map.put("store", "0");
                if (rackMsg.getRackId() != null) {
                    map.put("rackId", rackMsg.getRackId() + "");
                }
                //在扣新表库存
                List<ProductStockRackDo> rackDoList = productStockRackDao.getStockRackList(map);
                int goodQuantity = rackMsg.getQuantity();
                for (ProductStockRackDo rackDo : rackDoList) {
                    //单纯减库存，也要更新旧表库存
                    Map<String, Integer> resultMap = productStockRackService.dealWithOneRackStock(goodQuantity, 0, rackDo, StaticDict.Product_Flowing_Type.OrderRepair.getValue(),
                            null, "维修订单:" + et.getRepairNo() + (et.getRepairResult() != null && et.getRepairResult() == 1 ? "无法维修扣减库存" : "完成维修扣减库存"), userId);
                    int dGood = resultMap.get("dGood");
                    int dBad = resultMap.get("dBad");
                    if (dGood == 0 && dBad == 0) {
                        continue;
                    }
                    goodQuantity = resultMap.get("goodQuantity");
                    productStockDao.updateStockById(rackDo.getStockId(), dGood);
                    if (goodQuantity <= 0) {
                        break;
                    }
                }
                if (goodQuantity > 0) {
                    throw new BizException(SysConstant.StockRack_Good_NotEnough_New);
                }
            }
        }
    }


    /**
     * 无法维修
     *
     * @param userId
     */
    @Override
    public void cannotRepair(CannotRepairReq req, Long userId) {
        OrderRepairDo et = dao.selectById(req.getId());
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(et.getStatus())) {
            throw new BizException(SysConstant.OrderRepair_FinishRepair_Error);
        }
        OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>().eq(OrderRepairSkuDo::getRepairId, et.getId())
                .eq(OrderRepairSkuDo::getType, "sku"));
        et.setStatus(StaticDict.Order_Repair_Status_Type.Repaired.getValue());
        et.setUpdateBy(userId);
        et.setUpdateTime(new Date());
        if (skuDo.getCount() > 0) {
            et.setRepairResult(0);//维修结果无法维修
        } else {
            et.setRepairResult(1);//维修结果无法维修
        }
        et.setFaultReason(req.getFaultReason());
        dao.updateById(et);

        this.updateComponent(et, req.getComponentList(), 1, userId);


        //处理标签
        orderRepairLabelService.updateLabel(et.getId(), req.getLabelIds(), userId);

        //附件信息
        fileMoreService.dealFileList(req.getRepairFileList(), et.getId(), StaticDict.File_Type.RepairPic.getValue(), userId);

        //操作日志
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_CannotRepair.getValue(), req.getId(), userId, 9);


        List<StockRecordDo> list = stockRecordDao.selectList(new LambdaQueryWrapper<StockRecordDo>()
                .eq(StockRecordDo::getStorageId, et.getStorageId())
                .eq(StockRecordDo::getProductInfoId, skuDo.getProductId()).gt(StockRecordDo::getRepairingCount, 0));

        //解冻旧表库存
        int quantity = skuDo.getQuantity() - skuDo.getCount();
        this.dealRepairingCount(list, et.getRepairNo(), quantity, skuDo.getProductId(), 0, userId);
        //新表解冻
        //保存到新表 新表解冻库存
        List<ProductStockRackDo> rackDoList = this.getRackList(skuDo.getProductId(), et.getStorageId(), et.getCompanyId(), "2");//维修区
        int badQuantity = skuDo.getQuantity() - skuDo.getCount();
        this.reduceBadQuantity(rackDoList, badQuantity, "无法维修移除库存", userId);
    }


    /**
     * 完成指示
     */
    @Override
    public void finishIndicate(FinishIndicateReq req, Long userId) {
//        OrderRepairDo et = dao.selectById(req.getId());
//        if (et == null) {
//            throw new BizException(SysConstant.No_Data);
//        }
//        if (!StaticDict.Order_Repair_Status_Type.Repaired.getValue().equals(et.getStatus()) && !StaticDict.Order_Repair_Status_Type.Indicate.getValue().equals(et.getStatus())) {
//            //只有维修完成和客户指示才能 完成指示
//            throw new BizException(SysConstant.OrderRepair_Status_Error);
//        }
//        //如果维修结果是 无法维修，那么只能废弃
//        if (et.getRepairResult() == 1 && req.getIndicateResult() == 0) {
//            throw new BizException(SysConstant.OrderRepair_Indicate_ERROR);
//        }
//        OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>().eq(OrderRepairSkuDo::getRepairId, et.getId())
//                .eq(OrderRepairSkuDo::getType, "sku"));
//
//        if (req.getIndicateResult() == 1) {
//            //废弃
//            et.setStatus(StaticDict.Order_Repair_Status_Type.FinishIndicate.getValue());
//            et.setIndicateResult(1);//仓库完成指示 废弃
//            et.setUpdateTime(new Date());
//            et.setUpdateBy(userId);
//            dao.updateById(et);
//            //操作日志
//            operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_FinishIndicate_Discard.getValue(), req.getId(), userId, 9);
//            //废弃需要移除 冻结库存
//            List<StockRecordDo> list = stockRecordDao.selectList(new LambdaQueryWrapper<StockRecordDo>()
//                    .eq(StockRecordDo::getStorageId, et.getStorageId())
//                    .eq(StockRecordDo::getProductInfoId, skuDo.getProductId()).gt(StockRecordDo::getRepairingCount, 0));
//            //解冻旧表库存
//            int quantity = skuDo.getQuantity();
//            this.dealRepairingCount(list, et.getRepairNo(), quantity, skuDo.getProductId(), 0, userId);
//            //新表解冻
//            //保存到新表 新表解冻库存
//            Map<String, String> map = new HashMap<>();
//            map.put("productId", skuDo.getProductId() + "");
//            map.put("storageId", et.getStorageId() + "");
//            map.put("companyId", et.getCompanyId() + "");
//            map.put("store", "2");//维修区
//            List<ProductStockRackDo> rackDoList = productStockRackDao.getStockRackList(map);
//
//            int goodQuantity = skuDo.getQuantity();
//            for (ProductStockRackDo rackDo : rackDoList) {
//                //单纯减库存，
//                Map<String, Integer> resultMap = productStockRackService.dealWithOneRackStock(goodQuantity, 0, rackDo, StaticDict.Product_Flowing_Type.RackUpdate.getValue(), "废弃移除库存", userId);
//                int dGood = resultMap.get("dGood");
//                int dBad = resultMap.get("dBad");
//                if (dGood == 0 && dBad == 0) {
//                    continue;
//                }
//                goodQuantity = resultMap.get("goodQuantity");
//                productStockDao.updateStockById2(rackDo.getStockId(), dGood, dBad);
//                if (goodQuantity <= 0) {
//                    break;
//                }
//            }
//            if (goodQuantity > 0) {
//                throw new BizException(SysConstant.StockRack_Good_NotEnough_New);
//            }
//
//        } else {
//            //上架 需要去解冻库存
//            if (req.getSkuList() == null || req.getSkuList().size() == 0) {
//                throw new BizException(SysConstant.No_Data);
//            }
//
//            et.setStatus(StaticDict.Order_Repair_Status_Type.FinishIndicate.getValue());
//            et.setIndicateResult(0);
//            et.setUpdateTime(new Date());
//            et.setUpdateBy(userId);
//            dao.updateById(et);
//            //操作日志
//            operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_FinishIndicate_Grounding.getValue(), req.getId(), userId, 9);
//
//
//        }
    }


    public void dealRepairingCount(List<StockRecordDo> list, String repairNo, int quantity, Long productId, int type, Long userId) {
        if (quantity <= 0) {
            return;
        }
        for (StockRecordDo recordDo : list) {
            if (recordDo.getRepairingCount() == 0) {
                continue;
            }
            int onceCount = 0;
            if (recordDo.getRepairingCount() > quantity) {
                onceCount = quantity;
                quantity = 0;
            } else {
                onceCount = recordDo.getRepairingCount();
                quantity -= onceCount;
            }
            if (onceCount == 0) {
                continue;
            }
            recordDo.setRepairingCount(recordDo.getRepairingCount() - onceCount);
            if (type == 1) {
                recordDo.setCanSellCount(recordDo.getCanSellCount() + onceCount);
            }
            stockRecordDao.updateById(recordDo);
            stockLogDao.saveAutoSendOutLog(productId, recordDo.getShopId(), recordDo.getStorageId(),
                    type == 1 ? onceCount : -onceCount, recordDo.getCanSellCount(), recordDo.getCompanyId(), userId, repairNo);

            if (quantity <= 0) {
                break;
            }
        }

        if (quantity > 0) {
            ProductInfoDo productInfoDo = productInfoDao.selectObject(productId);
            throw new BizException(SysConstant.Product_OmsStock_NotEnough_Sku_Freeze, productInfoDo.getCommoditySku());
        }
    }

    /**
     * 收费初始化
     */
    @Override
    public ChargeInitRes chargeInit(Long id) {
        OrderRepairDo et = dao.selectById(id);
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.Repaired.getValue().equals(et.getStatus())) {
            //只有完成指示才能 收费
            throw new BizException(SysConstant.OrderRepair_Status_Error);
        }
        ChargeInitRes initRes = new ChargeInitRes();
        BeanUtils.copyProperties(et, initRes);
        if (initRes.getCurrency() == null) {
            initRes.setCurrency(DicBusinessItemConstant.CurrencyTypeJpy);
        }
        //sku信息
        List<OrderRepairSkuRes> skuList = this.getSkuList(id, et.getCompanyId(), et.getStorageId());
        initRes.setSkuList(skuList);
        //维修项目类型
        //故障标签id
        List<DicBusinessItemNewDo> itemNewDoList = dao.getLabelItemList(id);
        List<Long> labelIds = itemNewDoList.stream().map(DicBusinessItemNewDo::getId).collect(Collectors.toList());
        initRes.setLabelIds(labelIds);
        return initRes;
    }

    /**
     * 收费
     */
    @Override
    public void charge(ChargeReq req, Long userId) {
        OrderRepairDo et = dao.selectById(req.getId());
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }
        if (!StaticDict.Order_Repair_Status_Type.Repaired.getValue().equals(et.getStatus())) {
            //只有完成指示才能 收费
            throw new BizException(SysConstant.OrderRepair_Status_Error);
        }
        BeanUtils.copyProperties(req, et);
        et.setStatus(StaticDict.Order_Repair_Status_Type.Finish.getValue());
        et.setUpdateBy(userId);
        et.setUpdateTime(new Date());
        dao.updateById(et);
        //操作日志
        operateRecordService.operateAddRecord(StaticDict.Order_Repair_Operate_Type.OrderRepair_Charge.getValue(), req.getId(), userId, 9);
        //标签 先把标签都删了，再去新增标签
        orderRepairLabelService.updateLabel(et.getId(), req.getLabelIds(), userId);

        //扣钱 如果是人民币 转成日币扣钱
        double amountJP = et.getRepairCostTotal();
        if (DicBusinessItemConstant.CurrencyTypeRmb.equals(et.getCurrency())) {
            amountJP = MathUtils.numberFormat(et.getRepairCostTotal() / exchangeRateDao.getRateByType(et.getCurrency()), 2);
        }
        mCostService.add(7, et.getRepairNo() + "维修订单上架费", amountJP, null, et.getCompanyId(), et.getId());


    }

    private final String chars = "ABCDEFGHIZKLMNOPQRSTUVWXYZ";

    /**
     * 导出sn码，获取打印参数实体
     *
     * @param skuDo
     * @param et
     * @param userId
     * @return
     */
    public List<OrderRepairSnPrintEntity> getSnPrintEntity(OrderRepairSkuDo skuDo, OrderRepairDo et, Long userId) {
        List<OrderRepairSnPrintEntity> printEntityList = new ArrayList<>();


        ProductInfoDo productInfoDo = productInfoDao.selectObject(skuDo.getProductId());
        if (productInfoDo == null) {
            throw new BizException(SysConstant.Product_NotExist);
        }
        //先看 有没有生成过 sn码
        List<OrderRepairSnDo> snDoList = orderRepairSnDao.selectList(new LambdaQueryWrapper<OrderRepairSnDo>()
                .eq(OrderRepairSnDo::getRepairSkuId, skuDo.getId()).eq(OrderRepairSnDo::getRepairId, et.getId()));
        if (snDoList.size() == 0) {
            //生成sn码
            StringBuilder suffixBuilder = new StringBuilder();
            synchronized (this) {
                int count = 0;
                do {
                    suffixBuilder.setLength(0);
                    char c = chars.charAt((int) (Math.random() * 26));
                    suffixBuilder.append(et.getRepairNo().substring(4)).append(c).append(UUID.randomUUID().toString().substring(10, 12).replaceAll("-", ""));

                    //判断sn码是否存在
                    count = orderRepairSnDao.selectCount(new LambdaQueryWrapper<OrderRepairSnDo>().likeRight(OrderRepairSnDo::getSnNo, suffixBuilder.toString()));
                } while (count != 0);
            }
            for (int i = 0; i < skuDo.getQuantity(); i++) {
                String indexS = (i + 1) + "";
                StringBuilder index = new StringBuilder(indexS);
                while (index.length() < 3) {
                    index.insert(0, "0");
                }
                StringBuilder snBuilder = new StringBuilder();
                snBuilder.append(suffixBuilder).append(index);
                //生成sn码
                OrderRepairSnDo snDo = new OrderRepairSnDo();
                snDo.setRepairId(skuDo.getRepairId());
                snDo.setRepairSkuId(skuDo.getId());
                snDo.setSnNo(snBuilder.toString());
                snDo.setCreateBy(userId);
                snDo.setCreateTime(new Date());
                orderRepairSnDao.insert(snDo);
                printEntityList.add(getSinglePrintEntity(et, productInfoDo, snDo));
            }
        } else {
            for (OrderRepairSnDo snDo : snDoList) {
                printEntityList.add(getSinglePrintEntity(et, productInfoDo, snDo));
            }
        }
        return printEntityList;
    }

    public OrderRepairSnPrintEntity getSinglePrintEntity(OrderRepairDo et, ProductInfoDo productInfoDo, OrderRepairSnDo snDo) {
        OrderRepairSnPrintEntity entity = new OrderRepairSnPrintEntity();
        entity.setId(et.getId());
        entity.setCommoditySku(productInfoDo.getCommoditySku());
        entity.setSku("产品sku:" + productInfoDo.getCommoditySku());
        entity.setRepairNo(et.getRepairNo());
        entity.setSnNo(snDo.getSnNo());
        return entity;
    }

    @Override
    public List<OrderRepairDetailRes> batchExportInit(String[] ids) {
        List<OrderRepairDetailRes> list = new ArrayList<>();
        for (String id : ids) {
            list.add(this.detail(Long.parseLong(id)));
        }
        return list;
    }

    @Override
    public void batchExportRepair(BatchExportRepairReq req, Long userId, HttpServletResponse response) throws IOException {
        List<Long> ids = new ArrayList<>();
        for (ExportRepairReq exportRepairReq : req.getReqList()) {
            //先去保存部件信息
            OrderRepairDo et = dao.selectById(exportRepairReq.getId());
            if ((StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(et.getStatus()) ||
                    StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(et.getStatus()) ||
                    StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(et.getStatus()))) {
                this.updateComponent(et, exportRepairReq.getComponentList(), 0, userId);
            }
            ids.add(exportRepairReq.getId());
        }
        this.exportRepair(ids, response);
    }


    @Override
    public void exportRepair(ExportRepairReq req, Long userId, HttpServletResponse response) throws IOException {
        //先去保存部件信息
        OrderRepairDo et = dao.selectById(req.getId());
        if ((StaticDict.Order_Repair_Status_Type.ToCheck.getValue().equals(et.getStatus()) ||
                StaticDict.Order_Repair_Status_Type.Checked.getValue().equals(et.getStatus()) ||
                StaticDict.Order_Repair_Status_Type.Repairing.getValue().equals(et.getStatus()))) {
            this.updateComponent(et, req.getComponentList(), 0, userId);
        }

        //再去打印
        this.exportRepair(Arrays.asList(req.getId()), response);
    }


    /**
     * 导出sn
     */
    @Override
    public void printSn(String[] id, Long userId, HttpServletResponse response) {
        List<OrderRepairDo> list = dao.selectList(new LambdaQueryWrapper<OrderRepairDo>().in(OrderRepairDo::getId, Arrays.asList(id)).last(" order by id desc"));
        if (list.size() == 0) {
            throw new BizException(SysConstant.No_Data);
        }
        List<OrderRepairSnPrintEntity> snPrintList = new ArrayList<>();

        for (OrderRepairDo et : list) {
            OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>().eq(OrderRepairSkuDo::getRepairId, et.getId())
                    .eq(OrderRepairSkuDo::getType, "sku").last(" order by id desc limit 1"));
            if (skuDo == null) {
                throw new BizException(SysConstant.No_Data);
            }
            snPrintList.addAll(this.getSnPrintEntity(skuDo, et, userId));
        }


        //a4打印 一行三个
        String name = "sn码" + TimeUtils.getCurrentDateFormat("HHmmss");
        BarCodePdfUtils.repairPrintPdf(snPrintList, 50, 30, name, response);
    }

    @Override
    public void printSnSku(String id, String repairSkuId, Long userId, HttpServletResponse response) {
        OrderRepairDo et = dao.selectById(id);
        if (et == null) {
            throw new BizException(SysConstant.No_Data);
        }

//        OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>().eq(OrderRepairSkuDo::getRepairId, id).eq(OrderRepairSkuDo::getId, repairSkuId));
//        if (skuDo == null) {
//            throw new BizException(SysConstant.No_Data);
//        }
        OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>().eq(OrderRepairSkuDo::getRepairId, et.getId())
                .eq(OrderRepairSkuDo::getType, "sku").last(" order by id desc limit 1"));
        if (skuDo == null) {
            throw new BizException(SysConstant.No_Data);
        }
        List<OrderRepairSnPrintEntity> snPrintList = this.getSnPrintEntity(skuDo, et, userId);


        //a4打印 一行三个
        String name = "sn码_" + snPrintList.get(0).getCommoditySku() + "_" + TimeUtils.getCurrentDateFormat("HHmmss");
//        BarCodePdfUtils.repairPrintPdfA4(snPrintList, name, response);
        BarCodePdfUtils.repairPrintPdf(snPrintList, 50, 30, name, response);

    }

    /**
     * 导出维修单
     */
    public void exportRepair(List<Long> ids, HttpServletResponse response) throws IOException {
        Map<String, String> map = new HashMap<>();
        map.put("ids", StringUtils.join(ids, ","));
        List<OrderRepairPageRes> resList = this.getList(map);

        List<OrderRepairExportVo> exportVos = new ArrayList<>();

        for (OrderRepairPageRes et : resList) {
            OrderRepairExportVo exportVo = new OrderRepairExportVo();
            BeanUtils.copyProperties(et, exportVo);

            OrderRepairSkuDo skuDo = orderRepairSkuDao.selectOne(new LambdaQueryWrapper<OrderRepairSkuDo>().eq(OrderRepairSkuDo::getRepairId, et.getId())
                    .eq(OrderRepairSkuDo::getType, "sku").last(" order by id desc limit 1"));
            exportVo.setQuantity(skuDo.getQuantity());
            exportVo.setCount(skuDo.getCount());
            exportVo.setStatus(StaticDict.Order_Repair_Status_Type.getText(et.getStatus()));
            //维修时间
            if (et.getStatus().equals(StaticDict.Order_Repair_Status_Type.Repaired.getValue()) || et.getStatus().equals(StaticDict.Order_Repair_Status_Type.Finish.getValue())) {
                if (et.getBeginRepairTime() != null && et.getFinishRepairTime() != null) {
                    exportVo.setRepairingMin(DateUtils.differentMinByMillisecond(et.getBeginRepairTime(), et.getFinishRepairTime()));
                }
            }

            exportVos.add(exportVo);
        }
        ExcelUtils.exportExcel(exportVos, OrderRepairExportVo.class, "维修单" + "_" + TimeUtils.getCurrentDateFormat("HHmmss"), new ExportParams(), response);
    }

}
